import React, { useEffect, useRef, useState } from 'react';
import { UploadOutlined } from '@ant-design/icons';
import type { UploadFile, UploadProps } from 'antd';
import { Button, Upload, message } from 'antd';
import useUploadOss from '../../hook/useUploadOss.ts';
import { useConfig } from '../../hook/D8dConfigProvider.tsx';
import { hasHttpOrHttps } from '../../utils/fun.ts';

export interface FileInfo {
  url: string;
  name: string;
  format: string;
  size?: number;
  type?: string;
}

export interface AdminUploadProps extends Omit<UploadProps, 'customRequest' | 'value' | 'onChange'> {
  value?: string | string[]; // 单个文件 URL 或文件 URL 数组
  onChange?: (url?: string | string[], fileInfo?: FileInfo | FileInfo[]) => void; // 文件上传完成后的回调
  children?: React.ReactNode;
  maxSize?: number; // 最大文件大小（MB）
  acceptedFileTypes?: string[]; // 允许的文件类型
  maxCount?: number; // 最大文件数
  directory?: boolean; // 是否支持上传文件夹
  showUploadList?: boolean; // 是否展示文件列表
}

export interface SuccessResponse {
  status: 'done';
  name: string;
  uid: string;
  filePath: string;
}

const AdminUpload: React.FC<AdminUploadProps> = ({ 
  value,
  onChange,
  children,
  maxSize = 5, // 默认最大 5MB
  acceptedFileTypes = [], // 默认不限制文件类型
  maxCount = 1, // 默认单文件
  directory = false,
  showUploadList = true,
  ...restProps
}) => {
  const { upload } = useUploadOss();
  const { appConfig } = useConfig();
  const uploadRef = useRef<{ [key: string]: XMLHttpRequest }>({});
  
  // 处理 URL 格式
  const formatUrl = (path?: string) => {
    if (!path) return undefined;
    if (hasHttpOrHttps(path)) return path;
    return appConfig?.ossBaseUrl ? `${appConfig.ossBaseUrl}/${path}` : path;
  };
  
  // 将外部的 URL 转换为内部的 fileList
  const [fileList, setFileList] = useState<UploadFile[]>(() => {
    if (!value) return [];
    const urls = Array.isArray(value) ? value : [value];
    return urls.map((url, index) => ({
      uid: `-${index + 1}`,
      name: url.split('/').pop() || 'file',
      status: 'done',
      url: formatUrl(url),
      thumbUrl: formatUrl(url)
    }));
  });

  // 当外部 value 变化时，更新内部 fileList
  useEffect(() => {
    if (!value) {
      setFileList([]);
    } else {
      const urls = Array.isArray(value) ? value : [value];
      setFileList(urls.map((url, index) => ({
        uid: `-${index + 1}`,
        name: url.split('/').pop() || 'file',
        status: 'done',
        url: formatUrl(url),
        thumbUrl: formatUrl(url)
      })));
    }
  }, [value, appConfig?.ossBaseUrl]);

  // 验证文件大小和类型
  const validateFile = (file: File): boolean => {
    // 验证文件大小
    const isLessThanMaxSize = file.size / 1024 / 1024 < maxSize;
    if (!isLessThanMaxSize) {
      message.error(`文件必须小于 ${maxSize}MB!`);
      return false;
    }

    // 验证文件类型
    if (acceptedFileTypes.length > 0) {
      const isAcceptedType = acceptedFileTypes.includes(file.type);
      if (!isAcceptedType) {
        message.error(`只支持 ${acceptedFileTypes.join(', ')} 格式的文件!`);
        return false;
      }
    }

    return true;
  };

  const handleChange: UploadProps['onChange'] = ({ file, fileList: newFileList }) => {
    // console.log('AdminUpload onChange:', file, newFileList);
    
    // 更新内部状态
    setFileList(newFileList);
    
    // 处理上传成功的情况
    if (file.status === 'done') {
      // 收集所有已完成上传的文件信息
      const doneFiles = newFileList.filter(f => f.status === 'done');
      const urls = doneFiles.map(f => f.response.url).filter(Boolean);
      const fileInfos = doneFiles.map(f => ({
        url: f.response.url,
        name: f.name,
        format: f.name.split('.').pop()?.toLowerCase() || '',
        size: (f.originFileObj as File)?.size,
        type: f.type
      }));

      // 根据 maxCount 决定返回单个还是数组
      onChange?.(
        maxCount === 1 ? urls[0] : urls,
        maxCount === 1 ? fileInfos[0] : fileInfos
      );
    }
    
    // 处理上传失败的情况
    if (file.status === 'error') {
      message.error(`${file.name} 上传失败`);
    }
  };

  const onRemove = (file: UploadFile) => {
    // 如果文件正在上传中，取消上传
    const uploadId = (file as any).uploadId || file.uid;
    if (file.status === 'uploading' && uploadRef.current[uploadId]) {
      uploadRef.current[uploadId].abort();
      delete uploadRef.current[uploadId];
    }
    
    // 更新文件列表，移除被删除的文件
    const newFileList = fileList.filter(f => f.uid !== file.uid);
    setFileList(newFileList);

    // 收集剩余的文件 URL
    const urls = newFileList
      .filter(f => f.status === 'done')
      .map(f => f.url!)
      .filter(Boolean);

    // 根据 maxCount 决定返回单个 URL 还是数组
    onChange?.(maxCount === 1 ? urls[0] : urls.length ? urls : undefined);
    return true;
  };

  const customRequest: UploadProps['customRequest'] = async (options) => {
    const { 
      file, 
      onProgress, 
      onSuccess, 
      onError,
      filename: optFilename
    } = options;

    // 生成唯一的上传ID
    const uploadId = Date.now().toString();
    (file as any).uploadId = uploadId;

    try {
      await upload({
        file: file as Blob,
        onProgress: (event) => {
          // 确保进度在 0-100 之间
          const percent = Math.min(99.9, event.percent);
          onProgress?.({ percent });
        },
        onSuccess: (filePath) => {
          // 清理上传引用
          delete uploadRef.current[uploadId];
          
          if (onSuccess) {
            onSuccess({
              status: 'done',
              name: (file as File).name,
              uid: uploadId,
              url: filePath // 文件路径
            });
          }
        },
        onError: (error) => {
          // 清理上传引用
          delete uploadRef.current[uploadId];
          
          console.error('Upload failed:', error);
          const err = new Error(error.message || '上传失败');
          onError?.(err);
          
          // 显示错误信息
          let errorMessage = '上传失败';
          if (error.message) {
            errorMessage += `: ${error.message}`;
          }
          if (error.code) {
            errorMessage += ` (${error.code})`;
          }
          message.error(errorMessage);
        }
      });
    } catch (error) {
      console.error('Upload failed:', error);
      const err = error instanceof Error ? error : new Error('上传失败');
      onError?.(err);
      message.error(`上传失败: ${err.message}`);
    }
  };

  // 在组件卸载时清理消息和取消所有未完成的上传
  useEffect(() => {
    return () => {
      message.destroy();
      // 取消所有未完成的上传
      Object.values(uploadRef.current).forEach(xhr => {
        xhr.abort();
      });
      uploadRef.current = {};
    };
  }, []);

  return (
    <Upload
      fileList={fileList}
      onChange={handleChange}
      customRequest={customRequest}
      beforeUpload={validateFile}
      onRemove={onRemove}
      maxCount={maxCount}
      directory={directory}
      showUploadList={showUploadList}
      {...restProps}
    >
      {children || <Button icon={<UploadOutlined />}>点击上传</Button>}
    </Upload>
  );
};

export default AdminUpload; 